#include "BSP.h"
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

//----------------------BSP_UART----------------------//
#ifdef HAL_UART_MODULE_ENABLED
char UART_TxBuf[128] = {0};

int UART_Print(char *fmt, ...)
{
    int ret;
    va_list ap;
    va_start(ap, fmt);
    ret = vsprintf(UART_TxBuf, fmt, ap);
    va_end(ap);
    if (ret > 0)
    {
        HAL_UART_Transmit(&PRINT_UART, (uint8_t *)UART_TxBuf, ret, HAL_MAX_DELAY);
    }
    return ret;
}
#endif /* HAL_UART_MODULE_ENABLED */

//----------------------BSP_CAN----------------------//
#ifdef HAL_CAN_MODULE_ENABLED
void CAN_Filter_Init(CAN_HandleTypeDef *hcan)
{
    CAN_FilterTypeDef CAN_FilterInitStructure;
    CAN_FilterInitStructure.FilterActivation = ENABLE;
    CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDMASK;
    CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;
    CAN_FilterInitStructure.FilterIdHigh = 0x0000;
    CAN_FilterInitStructure.FilterIdLow = 0x0000;
    CAN_FilterInitStructure.FilterMaskIdHigh = 0x0000;
    CAN_FilterInitStructure.FilterMaskIdLow = 0x0000;
    CAN_FilterInitStructure.FilterBank = 0;
    CAN_FilterInitStructure.FilterFIFOAssignment = CAN_RX_FIFO0;
    HAL_CAN_ConfigFilter(hcan, &CAN_FilterInitStructure);
    HAL_CAN_Start(hcan);
    HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);
}

static CAN_TxHeaderTypeDef CAN_TxHeader;
static uint32_t CAN_TxMailbox = 0;

void CAN_Transmit(CAN_HandleTypeDef *hcan, uint16_t ID, uint8_t *Buf)
{

    if ((Buf != NULL))
    {
        CAN_TxHeader.StdId = ID;         /* 指定标准标识符，该值在0x00-0x7FF */
        CAN_TxHeader.IDE = CAN_ID_STD;   /* 指定将要传输消息的标识符类型 */
        CAN_TxHeader.RTR = CAN_RTR_DATA; /* 指定消息传输帧类型 */
        CAN_TxHeader.DLC = 8;            /* 指定将要传输的帧长度 */

        HAL_CAN_AddTxMessage(hcan, &CAN_TxHeader, Buf, &CAN_TxMailbox);
    }
}
#endif /* HAL_CAN_MODULE_ENABLED */

//---------------------------BSP_Interrupt--------------------------------//

//--------------------------------------------------------------------------
// GPIO Interrupt
#ifdef HAL_GPIO_MODULE_ENABLED

static void (**GPIO_EXTI[GPIOx_PIN_COUNT])(void);    // 指向函数指针的指针的数组
static uint8_t GPIO_Function_Count[GPIOx_PIN_COUNT]; // 存储函数数量的数组

/**
 * 联接GPIO中断源和中断回调函数
 * 应输入GPIO引脚, 回调函数个数以及回调函数的地址
 */
void AttachInterrupt_GPIO(uint16_t GPIO_Pin, int Callback_count, ...)
{
    uint8_t index = 0;

    // 获得index
    while (GPIO_Pin != 1)
    {
        GPIO_Pin >>= 1;
        index++;
    }

    GPIO_EXTI[index] = (void *)malloc(Callback_count * sizeof(void));
    GPIO_Function_Count[index] = Callback_count;

    va_list arg;
    va_start(arg, Callback_count);

    for (uint8_t i = 0; i < Callback_count; i++)
    {
        GPIO_EXTI[index][i] = va_arg(arg, void *);
    }

    va_end(arg);
}

// GPIO中断回调
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
    uint8_t index = 0;

    // 获得index
    while (GPIO_Pin != 1)
    {
        GPIO_Pin >>= 1;
        index++;
    }

    for (uint8_t i = 0; i < GPIO_Function_Count[index]; i++)
    {
        GPIO_EXTI[index][i]();
    }
}
#endif /* HAL_GPIO_MODULE_ENABLED */

//--------------------------------------------------------------------------
// TIM Interrupt
#ifdef HAL_TIM_MODULE_ENABLED

static void (**TIM_Base_Interrupt[TIMx_COUNT])(void); // 指向函数指针的指针的数组
static uint8_t TIM_Base_Function_Count[TIMx_COUNT];   // 存储函数数量的数组

/**
 * 联接TIM Base中断源和中断回调函数
 * 应输入TIM源, 回调函数个数以及回调函数的地址
 */
void AttachInterrupt_TIM_Base(TIM_HandleTypeDef *htim, int Callback_count, ...)
{
    uint8_t index = 0;

    // 获得index
    if (htim->Instance == TIM1)
        index = 0;
    else if (htim->Instance == TIM2)
        index = 1;
    else if (htim->Instance == TIM3)
        index = 2;
    else if (htim->Instance == TIM4)
        index = 3;
    else if (htim->Instance == TIM5)
        index = 4;
    else if (htim->Instance == TIM6)
        index = 5;
    else if (htim->Instance == TIM7)
        index = 6;
    else if (htim->Instance == TIM8)
        index = 7;

    TIM_Base_Interrupt[index] = (void *)malloc(Callback_count * sizeof(void));
    TIM_Base_Function_Count[index] = Callback_count;

    va_list arg;
    va_start(arg, Callback_count);

    for (uint8_t i = 0; i < Callback_count; i++)
    {
        TIM_Base_Interrupt[index][i] = va_arg(arg, void *);
    }

    va_end(arg);
}

// TIM Base中断回调
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    uint8_t index = 0;

    // 获得index
    if (htim->Instance == TIM1)
        index = 0;
    else if (htim->Instance == TIM2)
        index = 1;
    else if (htim->Instance == TIM3)
        index = 2;
    else if (htim->Instance == TIM4)
        index = 3;
    else if (htim->Instance == TIM5)
        index = 4;
    else if (htim->Instance == TIM6)
        index = 5;
    else if (htim->Instance == TIM7)
        index = 6;
    else if (htim->Instance == TIM8)
        index = 7;
#ifndef TIM9
    else if (htim->Instance == TIM9)
        index = 8;
#endif
#ifndef TIM10
    else if (htim->Instance == TIM10)
        index = 9;
#endif
#ifndef TIM11
    else if (htim->Instance == TIM11)
        index = 10;
#endif
#ifndef TIM12
    else if (htim->Instance == TIM12)
        index = 11;
#endif
#ifndef TIM13
    else if (htim->Instance == TIM13)
        index = 12;
#endif
#ifndef TIM14
    else if (htim->Instance == TIM14)
        index = 13;
#endif

    for (uint8_t i = 0; i < TIM_Base_Function_Count[index]; i++)
    {
        TIM_Base_Interrupt[index][i]();
    }
}
#endif /* HAL_TIM_MODULE_ENABLED */

//--------------------------------------------------------------------------
// UART Interrupt
#ifdef HAL_UART_MODULE_ENABLED

static void (**UART_Interrupt[UARTx_COUNT])(uint8_t *pData, uint8_t size); // 指向函数指针的指针的数组
static uint8_t UART_Function_Count[UARTx_COUNT];                           // 存储函数数量的数组

// UART接收数据缓冲
static uint8_t UARTx_RxBuf_Size[UARTx_COUNT];
static uint8_t *UARTx_RxBuf[UARTx_COUNT];

/**
 * 联接UART中断源和中断回调函数
 * 应输入UART源, 回调函数个数以及回调函数的地址
 */
void AttachInterrupt_UART(UART_HandleTypeDef *huart, uint8_t RxBuf_Size, int Callback_count, ...)
{
    uint8_t index = 0;

    // 获得index
    if (huart->Instance == USART1)
        index = 0;
    else if (huart->Instance == USART2)
        index = 1;
#ifdef USART3
    else if (huart->Instance == USART3)
        index = 2;
#endif /* USART3 */
#ifdef UART4
    else if (huart->Instance == UART4)
        index = 3;
#endif /* UART4 */
#ifdef UART5
    else if (huart->Instance == UART5)
        index = 4;
#endif /* UART5 */
#ifdef USART6
    else if (huart->Instance == USART6)
        index = 5;
#endif /* USART6 */

    UART_Interrupt[index] = (void *)malloc(Callback_count * sizeof(void));
    UART_Function_Count[index] = Callback_count;
    UARTx_RxBuf_Size[index] = RxBuf_Size;
    UARTx_RxBuf[index] = (uint8_t *)malloc(RxBuf_Size * sizeof(uint8_t));

    va_list arg;
    va_start(arg, Callback_count);

    for (uint8_t i = 0; i < Callback_count; i++)
    {
        UART_Interrupt[index][i] = va_arg(arg, void *);
    }

    HAL_UARTEx_ReceiveToIdle_IT(huart, UARTx_RxBuf[index], UARTx_RxBuf_Size[index]);

    va_end(arg);
}

// UART空闲中断回调
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    uint8_t index = 0;

    // 获得index
    if (huart->Instance == USART1)
        index = 0;
    else if (huart->Instance == USART2)
        index = 1;
#ifdef USART3
    else if (huart->Instance == USART3)
        index = 2;
#endif /* USART3 */
#ifdef UART4
    else if (huart->Instance == UART4)
        index = 3;
#endif /* UART4 */
#ifdef UART5
    else if (huart->Instance == UART5)
        index = 4;
#endif /* UART5 */
#ifdef USART6
    else if (huart->Instance == USART6)
        index = 5;
#endif /* USART6 */

    for (uint8_t i = 0; i < UART_Function_Count[index]; i++)
    {
        UART_Interrupt[index][i](UARTx_RxBuf[index], UARTx_RxBuf_Size[index]);
    }

    HAL_UARTEx_ReceiveToIdle_IT(huart, UARTx_RxBuf[index], UARTx_RxBuf_Size[index]);
}
#endif /* HAL_UART_MODULE_ENABLED */

//--------------------------------------------------------------------------
// CAN Interrupt
#ifdef HAL_CAN_MODULE_ENABLED

static void (**CAN_Interrupt[CANx_COUNT])(CAN_RxHeaderTypeDef *pHeader, uint8_t *pBuf); // 指向函数指针的指针的数组
static uint8_t CAN_Function_Count[CANx_COUNT];                                          // 存储函数数量的数组

// CAN外设句柄
static CAN_RxHeaderTypeDef CAN_RxHeader;
static uint8_t *CAN_RxBuf[CANx_COUNT];

void AttachInterrupt_CAN(CAN_HandleTypeDef *hcan, uint8_t RxBuf_Size, int Callback_count, ...)
{
    uint8_t index = 0;

    // 获得index
    if (hcan->Instance == CAN1)
        index = 0;
#ifdef CAN2
    else if (hcan->Instance == CAN2)
        index = 1;
#endif /* CAN2 */

    CAN_Interrupt[index] = (void *)malloc(Callback_count * sizeof(void));
    CAN_Function_Count[index] = Callback_count;
    CAN_RxBuf[index] = (uint8_t *)malloc(Callback_count * sizeof(uint8_t));

    va_list arg;
    va_start(arg, Callback_count);

    for (uint8_t i = 0; i < Callback_count; i++)
    {
        CAN_Interrupt[index][i] = va_arg(arg, void *);
    }

    va_end(arg);
}

// CAN中断回调
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    uint8_t index = 0;

    // 获得index
    if (hcan->Instance == CAN1)
        index = 0;
#ifdef CAN2
    else if (hcan->Instance == CAN2)
        index = 1;
#endif /* CAN2 */

    HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &CAN_RxHeader, CAN_RxBuf[index]);

    for (uint8_t i = 0; i < CAN_Function_Count[index]; i++)
    {
        CAN_Interrupt[index][i](&CAN_RxHeader, CAN_RxBuf[index]);
    }
}
#endif /* HAL_CAN_MODULE_ENABLED */
